package com.apps.sworld.dao;

import com.apps.sexctption.DataException;
import com.apps.sexctption.NullException;
import com.apps.shelper.ClassHelper;
import com.apps.sutils.StringUtils;
import com.apps.sworld.enums.TimeUnit;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.apps.sannotation.constraints.NoNull;
import com.apps.sannotation.identity.OrderId;
import com.apps.saspect.ValidMethod;
import com.apps.shelper.AnnotationHelper;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 订单抽象类
 * @param <T>
 */
public interface sOrder<T> extends sShop<T> {

    /**
     * 获取模型被@MemberId注解的字段的名称
     * @return
     */
    default String getOrderIdName()
    {
        return AnnotationHelper.getAnnotationFieldName(OrderId.class,currentModelClass());
    }
    /**
     * 删除这张表属于某用户的所有数据
     * @param order_id
     */
    @ValidMethod
    default void deleteByOrderId(@NoNull Integer order_id)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getOrderIdName(),order_id);
        delete(wrapper);
    }
    /**
     * 按用户id查询统计数据条数
     * @param order_id
     * @return
     */
    @ValidMethod
    default int countByOrderId(@NoNull Integer order_id)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getOrderIdName(),order_id);
        return count(wrapper);
    }
    /**
     * 按用户id查询该用户在该张表的数据是否为空
     * @param order_id
     * @return
     */
    @ValidMethod
    default boolean isEmptyByOrderId(@NoNull Integer order_id)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getOrderIdName(),order_id);
        return isEmpty(wrapper);
    }

    @ValidMethod
    default boolean isEmptyByOrderId(@NoNull Integer order_id,@NoNull QueryWrapper<T> wrapper)
    {
        wrapper.eq(getOrderIdName(),order_id);
        return isEmpty(wrapper);
    }
    /**
     * 按用户ID查出所有数据,无排序
     * @param order_id
     * @return
     */
    @ValidMethod
    default List<T> queryByOrderId(@NoNull Integer order_id)
    {
        return queryByFieldValue(getOrderIdName(),order_id);
    }

    @ValidMethod
    default List<T> queryByOrderId(@NoNull Integer order_id,@NoNull QueryWrapper<T> wrapper)
    {
        wrapper.eq(getOrderIdName(),order_id);
        return query(wrapper);
    }
    /**
     * 按创建时间进行按年月日小时查询,传入的是字符串格式:2021090306 这样的格式
     * @param member_id
     * @param date
     * @param timeUnit
     * @return
     */
    @ValidMethod
    default List<T> queryGmtCreateByOrderId(@NoNull Integer member_id,@NoNull String date, @NoNull TimeUnit timeUnit)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getOrderIdName(),member_id);
        return queryByGmtCreate(wrapper,date,timeUnit);
    }
    /**
     * 按创建时间进行按年月日小时分页查询,传入的是字符串格式:2021090306 这样的格式
     * @param member_id
     * @param date 传入的是字符串格式:2021090306
     * @param timeUnit
     * @return
     */
    @ValidMethod
    default IPage<T> pageQueryGmtCreateByOrderId(@NoNull Integer member_id,@NoNull String date, @NoNull TimeUnit timeUnit,int pageNo, int pageSize)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getOrderIdName(),member_id);
        return pageQueryByGmtCreate(wrapper,date,timeUnit,pageNo,pageSize);
    }
    /**
     * 按时间区间查询
     * @param order_id
     * @param start
     * @param end
     * @return
     */
    @ValidMethod
    default List<T> queryTimeIntervalByOrderId(@NoNull Integer order_id, @NoNull LocalDateTime start, @NoNull LocalDateTime end)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getOrderIdName(),order_id);
        return queryTimeInterval(wrapper,start,end);
    }


    /**
     * 按用户id查询一条记录
     * @param order_id
     * @return
     */
    @ValidMethod
    default T getOneByOrderId(@NoNull Integer order_id){
        return getOneByFieldValue(getOrderIdName(),order_id);
    }

    /**
     * 获取不到就创建
     * @param order_id
     * @param t
     * @return
     */
    @ValidMethod
    default T getOneByOrderId(@NoNull Integer order_id,@NoNull T t){
        T result = getOneByOrderId(order_id);
        if(null == result)
        {
            String filedName=AnnotationHelper.getAnnotationFieldName(OrderId.class,t.getClass());
            if(StringUtils.isEmpty(filedName))
                throw new NullException("订单id不存在或没添加注解进行标识");
            Object filedValue= ClassHelper.getFiledValue(t,filedName);
            if(null== filedValue) {
                ClassHelper.setFiledValue(filedName, t, order_id);
                filedValue=order_id;
            }
            if(!filedValue.equals(order_id))
                throw new DataException("模型的订单id值必须等于传入的订单id");
            return saveToDB(t);
        }
        return result;
    }

    /**
     * 按用户ID分页查询用户的数据,无排序
     * @param order_id
     * @param pageNo
     * @param pageSize
     * @return
     */
    @ValidMethod
    default IPage<T> pageQueryByOrderId(@NoNull Integer order_id, int pageNo, int pageSize){
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getOrderIdName(),order_id);
        return pageQuery(wrapper,pageNo,pageSize);
    }

    @ValidMethod
    default IPage<T> pageQueryByOrderId(@NoNull Integer order_id, int pageNo, int pageSize,@NoNull QueryWrapper<T> wrapper){
        wrapper.eq(getOrderIdName(),order_id);
        return pageQuery(wrapper,pageNo,pageSize);
    }

    @ValidMethod
    default IPage<T> pageQueryTimeIntervalByOrderId(@NoNull Integer order_id, @NoNull LocalDateTime start, @NoNull LocalDateTime end, int pageNo, int pageSize)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getOrderIdName(),order_id);
        return pageQueryTimeInterval(wrapper,start,end,pageNo,pageSize);
    }

    @ValidMethod
    default T updateOneFieldByOrderId(@NoNull Integer order_id,@NoNull String fieldname,@NoNull Object value)
    {
        T t=getOneByOrderId(order_id);
        if(null == t)
            throw new NullException("order_id为"+order_id+"的记录不存在");
        ClassHelper.setFiledValue(fieldname,t,value);
        return updateById(t);
    }
}
